package io.github.mymonstercat.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.benjaminwan.ocrlibrary.OcrResult;
import com.benjaminwan.ocrlibrary.Point;
import com.benjaminwan.ocrlibrary.TextBlock;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.mymonstercat.Model;
import io.github.mymonstercat.config.properties.TicketComparisonBean;
import io.github.mymonstercat.config.properties.TicketComparisonProperties;
import io.github.mymonstercat.config.properties.TicketUnifyBean;
import io.github.mymonstercat.entity.*;
import io.github.mymonstercat.entity.attachmentCheck.AttachmentResponse;
import io.github.mymonstercat.ocr.InferenceEngine;
import io.github.mymonstercat.ocr.config.HardwareConfig;
import io.github.mymonstercat.ocr.config.ParamConfig;
import io.github.mymonstercat.service.FileWarningService;
import io.github.mymonstercat.tools.model.AiResponse;
import io.github.mymonstercat.utils.GetJsonData;
import io.github.mymonstercat.utils.HwNLPUtils;
import io.github.mymonstercat.utils.HwOCRUtils;
import io.github.mymonstercat.utils.SpatialSimilarityCompare;
import io.github.mymonstercat.utils.TextInfoTransformer;
import io.github.mymonstercat.utils.baidu.BaiduNLPUtils;
import io.github.mymonstercat.utils.baidu.BaiduOCRUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.simmetrics.StringMetric;
import org.simmetrics.metrics.StringMetrics;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FileWarningServiceImpl implements FileWarningService {

    @Value("${file.threshold}")
    private String threshold;

    @Value("${location.isEnabled}")
    private String isEnabled;

    @Value("${file.upload.window}")
    private String window;

    @Value("${file.upload.linux}")
    private String linux;

    @Value("${weight.text}")
    private Double textWeight;

    @Value("${weight.location}")
    private Double locationWeight;

    @Autowired
    private HwNLPUtils hwNLPUtils;

    @Autowired
    private SpatialSimilarityCompare spatialSimilarityCompare;

    @Resource
    private Environment environment;

    @Resource
    private GetJsonData getJsonData;

    @Resource
    private LocationProperties locationProperties;

    @Resource
    private TicketComparisonProperties ticketComparisonProperties;

    public static final String LEVENSHTEIN = "levenshtein";

    public static final String EQUALS = "equals";

    public static final String START = "equalsStart";

    public static final String REGEX = "[^\\p{L}\\p{N}\\u4e00-\\u9fa5]";

    public static ParamConfig PARAM_CONFIG = ParamConfig.getDefaultConfig();

    public static InferenceEngine ENGINE = InferenceEngine.getInstance(Model.ONNX_PPOCR_V4, new HardwareConfig(Runtime.getRuntime().availableProcessors() / -1, -1));

    static {
        PARAM_CONFIG.setDoAngle(true);
        PARAM_CONFIG.setMostAngle(true);
        PARAM_CONFIG.setPadding(20);
    }

    /**
     * 文件上传
     *
     * @param file 待上传文件
     * @param path 路径
     * @param name 文件名
     */
    @Override
    public void uploadFile(MultipartFile file, String path, String name) throws IOException {
        File destinationFile = new File(path);

        if (!destinationFile.exists()) {
            boolean b = destinationFile.mkdirs();
        }
        OutputStream fos = new FileOutputStream(path + name);
        FileInputStream fis = (FileInputStream) file.getInputStream();
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = fis.read(buffer)) != -1) {
            fos.write(buffer, 0, bytesRead);
        }
        fis.close();
        fos.close();
    }

    /**
     * 相似度计算
     *
     * @param file     待计算文件
     * @param fileName 文件名
     * @param path     路径
     * @param osName   系统名称
     * @return String
     */
    @Override
    public String getRate(MultipartFile file, String fileName, String path, String osName) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        // 阈值
        if (StringUtils.isBlank(threshold)) {
            threshold = "0.6";
        }
        // 普联不识别并且相似度小于60的文件保存位置
        String dissatisfy;
        if (osName.startsWith("Windows")) {
            dissatisfy = environment.getProperty("file.save.dissatisfy.window");
        } else {
            dissatisfy = environment.getProperty("file.save.dissatisfy.linux");
        }
        // 普联不识别并且相似度大于等于60的文件保存位置
        String satisfy;
        if (osName.startsWith("Windows")) {
            satisfy = environment.getProperty("file.save.satisfy.window");
        } else {
            satisfy = environment.getProperty("file.save.satisfy.linux");
        }
        double target = Double.parseDouble(threshold) * 100d;
        // 开始识别
        OcrResult ocrResult = ENGINE.runOcr(path + fileName, PARAM_CONFIG);
        ArrayList<TextBlock> arr = ocrResult.getTextBlocks();
        // 创建一个需要二维数组请求参数
        ArrayList<CenterPoint> boxPointLists = new ArrayList<>();
        // 获取指定的文本的坐标
        ArrayList<CenterPoint> originBoxPointLists = new ArrayList<>();
        // 最终结果
        List<Double> result = new ArrayList<>();
        TicketComparisonBean bean = null;
        // 确定票据属于哪个省
        List<TicketComparisonBean> ruleList = ticketComparisonProperties.getRuleList();
        for (TicketComparisonBean ticketComparisonBean : ruleList) {
            List<String> province = ticketComparisonBean.getProvince();
            for (String s : province) {
                for (TextBlock t : arr) {
                    String str = Pattern.compile(REGEX).matcher(t.getText()).replaceAll("");
                    if (str.contains(s)) {
                        bean = ticketComparisonBean;
                    }
                }
            }
        }
        // 非标准特征的相似度计算
        if (bean == null) {
            List<TicketUnifyBean> unifyList = ticketComparisonProperties.getUnifyList();
            for (TicketUnifyBean ticketUnifyBean : unifyList) {
                List<String> values = ticketUnifyBean.getValues();
                for (String value : values) {
                    for (TextBlock t : arr) {
                        String str = Pattern.compile(REGEX).matcher(t.getText()).replaceAll("");
                        if (EQUALS.equals(ticketUnifyBean.getCalculationRule()) && value.equals(str)) {
                            uploadFile(file, satisfy, fileName);
                            return "100";
                        }
                    }
                }
            }
            uploadFile(file, dissatisfy, fileName);
            return "0";
        }
        // 标准特征的相似度计算
        for (String value : bean.getValues()) {
            List<Double> rates = new ArrayList<>();
            for (TextBlock t : arr) {
                String str = Pattern.compile(REGEX).matcher(t.getText()).replaceAll("");
                List<String> exclude = bean.getExclude();
                if (exclude != null && exclude.size() > 0) {
                    for (String exc : exclude) {
                        if (str.contains(exc)) {
                            uploadFile(file, dissatisfy, fileName);
                            return "0";
                        }
                    }
                }
                if (LEVENSHTEIN.equals(bean.getCalculationRule())) {
                    StringMetric levenshtein = StringMetrics.levenshtein();
                    double similarity = levenshtein.compare(value, str) * 100d;
                    if (similarity >= target) {
                        rates.add(similarity);
                        // 计算文本块位置图形的相似度
                        if (isEnabled.equals("true")) {
                            // 获取需要对比的文本块坐标
                            List<Double> coordinates = SpatialSimilarityCompare.findCoordinates(locationProperties.getPoints(), value);
                            if (coordinates != null) {
                                CenterPoint centerPoint = new CenterPoint();
                                centerPoint.setX(coordinates.get(0));
                                centerPoint.setX(coordinates.get(1));
                                originBoxPointLists.add(centerPoint);
                            }
                            // 获取当前本本块的坐标
                            ArrayList<Point> boxPoint = t.getBoxPoint();
                            // 获取中心点的坐标
                            CenterPoint centerPoint = SpatialSimilarityCompare.getCenterPoint(boxPoint);
                            // 将中心点坐标添加到数组中
                            boxPointLists.add(centerPoint);
                        }
                    }
                }
                if (EQUALS.equals(bean.getCalculationRule())) {
                    if (value.equals(str)) {
                        uploadFile(file, satisfy, fileName);
                        return "100";
                    }
                }
                if (START.equals(bean.getCalculationRule())) {
                    if (value.equals(str) || str.startsWith(value)) {
                        uploadFile(file, satisfy, fileName);
                        return "100";
                    }
                }
            }
            if (rates.size() > 0) {
                BigDecimal average = rates.stream()
                        .map(BigDecimal::valueOf)
                        .reduce(BigDecimal.ZERO, BigDecimal::add)
                        .divide(BigDecimal.valueOf(rates.size()), 2, RoundingMode.HALF_UP);
                result.add(average.doubleValue());
                if (isEnabled.equals("true")) {
                    // 将标准坐标和识别的坐标转换为double[][]
                    double[][] doubleBoxPointLists = SpatialSimilarityCompare.toDoubleArray(boxPointLists);
                    double[][] doubleOriginBoxPointLists = SpatialSimilarityCompare.toDoubleArray(originBoxPointLists);
                    // 请求python服务的接口
                    String s1 = spatialSimilarityCompare.requestPyApi(doubleBoxPointLists, doubleOriginBoxPointLists);
                    PyResult responseData = objectMapper.readValue(s1, PyResult.class);
                    if (responseData.getStatus().equals("success")) {
                        System.out.println("相似度" + responseData.getResult());
                    }
                }
            }
        }
        if (result.size() > 0) {
            uploadFile(file, satisfy, fileName);
            return String.valueOf(result.stream().max(Comparator.naturalOrder()).orElse(0d));
        }
        uploadFile(file, dissatisfy, fileName);
        return "0";
    }

    @Override
    public Body getRate(String path, String name) {
        Body body = new Body();
        // 阈值
        if (StringUtils.isBlank(threshold)) {
            threshold = "0.6";
        }
        double target = Double.parseDouble(threshold) * 100d;
        try {
            // 计算相似度
            String rate = getCalculateRate(path);
            body.setCode("200");
            body.setRate(rate);
            if (Double.compare(Double.parseDouble(rate), target) >= 0) {
                body.setMessage("系统通过废票特征计算得出概率为：" + rate + "%。疑似票据版本过期，请人工核对!");
                body.setData("true");
            } else {
                body.setMessage("");
                body.setData("false");
            }
            // 计算完成后删除文件
            File f = new File(path);
            if (f.exists() && f.isFile()) {
                if (f.delete()) {
                    log.info(path + "：文件删除成功");
                } else {
                    log.info(path + "：文件删除失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return body;
    }

    /**
     * 升级后的票据预警系统
     *
     * @param path 文件路径
     * @return String 概率
     */
    private String getCalculateRate(String path) throws Exception {
        List<OcrTempateConfigs> json = this.getJson();
        // 定义文本相似度
        double textSim = 0.0;
        // 定义版面相似度
        double locationSim = 0.0;
        // 最终相似度
        double resultSim;

        // 定义一个是否判断版面相似度的标志
        boolean locationFlag = true;


        // 使用百度 OCR 识别文本
        ArrayList<TextBlock> baiduResult = BaiduOCRUtils.recognizeGeneralText(path);

        // 将百度 OCR 结果转换为 OCRStandardRes
        TextInfoTransformer textInfoTransformer = new TextInfoTransformer();
        OCRStandardRes ocrStandardRes = textInfoTransformer.baiduOCRTransform(baiduResult);

//        // OCR开始识别
//        String resstr = HwOCRUtils.recognizeGeneralText(path);
////        String resstr = Objects.requireNonNull(hwocrres.body()).string();
//        HwResult hwResult = JSONObject.parseObject(resstr, HwResult.class);
//        // 华为OCR的结果进行转换
//        TextInfoTransformer textInfoTransformer = new TextInfoTransformer();
//        OCRStandardRes ocrStandardRes = textInfoTransformer.hwOCRTransform(hwResult);

        // 判断票据的特征值
        String characteristic = getCharacteristic(ocrStandardRes.getWordsBlockList());
        if (StringUtils.isNotBlank(characteristic)) {
            OcrTempateConfigs config = null;
            Optional<OcrTempateConfigs> first = json.stream().filter(obj -> characteristic.equals(obj.getOcrText())).findFirst();
            if (first.isPresent()) {
                config = first.get();
            }
            // 数据库中查询到样本数据
            if (config != null && config.getOcrTempateConfigsId() != null) {
                // 判断数据类别
                if ("1".equals(config.getFeatureType())) {
                    OcrTempateConfigs finalConfig = config;
                    List<OcrTempateConfigs> result =
                            json.stream().filter(obj -> finalConfig.getOcrTemplateId().equals(obj.getOcrTemplateId())).collect(Collectors.toList());
                    List<String> ocrtexts = result.stream()
                            .map(OcrTempateConfigs::getOcrText)
                            .collect(Collectors.toList());
                    List<String> locations = result.stream()
                            .map(OcrTempateConfigs::getBoxPoint)
                            .collect(Collectors.toList());
                    OCRStandardRes sqlocrStandardRes = textInfoTransformer.sqlResultTransform(ocrtexts, locations);
                    List<OCRStandardRes.wordsBlock> configWordsList = sqlocrStandardRes.getWordsBlockList();


                    List<Double> rates = new ArrayList<>();
                    double target = Double.parseDouble(threshold) * 100d;
                    List<List<Double>> curCenterPointLists = new ArrayList<>();
                    List<List<Double>> configCenterPointLists = new ArrayList<>();
                    for (OCRStandardRes.wordsBlock configWordsBlock : configWordsList) {
                        String value = configWordsBlock.getWords();
                        // 获取需要对比的文本块坐标
                        List<List<Double>> configCoordinates = configWordsBlock.getLocation();
                        // 获取配置文本块坐标的中心坐标
                        List<Double> configCenterCoordinates = SpatialSimilarityCompare.calculateCenter(configCoordinates);
                        configCenterPointLists.add(configCenterCoordinates);

                        for (OCRStandardRes.wordsBlock t : ocrStandardRes.getWordsBlockList()) {
                            String str = Pattern.compile(REGEX).matcher(t.getWords()).replaceAll("");
                            StringMetric levenshtein = StringMetrics.levenshtein();
                            double similarity = levenshtein.compare(value, str) * 100d;
                            if (similarity >= target) {
                                rates.add(similarity);
                                // 计算文本块位置图形的相似度
                                if (isEnabled.equals("true")) {
                                    // 获取当前本本块的坐标
                                    List<List<Double>> curCoordinates = t.getLocation();
                                    // 获取中心点的坐标
                                    List<Double> centerCoordinates = SpatialSimilarityCompare.calculateCenter(curCoordinates);
                                    // 将中心点坐标添加到数组中
                                    curCenterPointLists.add(centerCoordinates);
                                }
                                // 如果找到相似度大于0.6的就停止
                                break;
                            }
                        }
                    }
                    if (rates.size() > 0) {
                        BigDecimal average = rates.stream()
                                .map(BigDecimal::valueOf)
                                .reduce(BigDecimal.ZERO, BigDecimal::add)
                                .divide(BigDecimal.valueOf(ocrtexts.size()), 2, RoundingMode.HALF_UP);
                        textSim = average.doubleValue();

                        if (curCenterPointLists.size() != configCenterPointLists.size()){
                            locationFlag = false;
                        }

                        if (isEnabled.equals("true") || locationFlag) {
                            // 将标准坐标和识别的坐标转换为double[][]
                            double[][] doubleBoxPointLists = SpatialSimilarityCompare.convertListToArray(curCenterPointLists);
                            double[][] doubleOriginBoxPointLists = SpatialSimilarityCompare.convertListToArray(configCenterPointLists);
                            // 请求python服务的接口
                            String s1 = spatialSimilarityCompare.requestPyApi(doubleBoxPointLists, doubleOriginBoxPointLists);
                            ObjectMapper objectMapper = new ObjectMapper();
                            PyResult responseData = objectMapper.readValue(s1, PyResult.class);
                            if (responseData.getStatus().equals("success")) {
                                locationSim = responseData.getResult();
                                System.out.println("相似度" + responseData.getResult());
                            } else {
                                // 如果python接口 返回失败 就不判断版面相似度了
                                locationFlag = false;
                            }
                        }
                    }

                    // 如果只有一个特征，则不判断版面相似度。
                    if (ocrtexts.size() == 1 || !locationFlag) {
                        return String.valueOf(textSim);
                    }

                    // 如果有两个及以上特征，再计算版面相似度
                    // 版面相似度的权重 + 文字相似度的权重
                    resultSim = textSim * textWeight + locationSim * 100d * locationWeight;
                    return String.valueOf(resultSim);
                }
                if ("2".equals(config.getFeatureType())) {
                    // 无样本有票据代码
                    return getRateByBillCode(ocrStandardRes.getWordsBlockList(), config);
                }
            }
        }
        // 无样本无票据代码
        return getRateByNoSampleByNLP(ocrStandardRes.getWordsBlockList());
    }

    /**
     * 无样本无票据代码计算相似度
     *
     * @param arr OCR识别结果
     * @return String 结果
     */
    private String getRateByNoSample(List<OCRStandardRes.wordsBlock> arr) throws IOException {
        List<OcrTempateConfigs> json = this.getJson();
        List<OcrTempateConfigs> list =
                json.stream().filter(obj -> "3".equals(obj.getFeatureType())).collect(Collectors.toList());
        List<Double> result = new ArrayList<>();
        Double textSim = 0.0;
        for (OcrTempateConfigs configs : list) {
            for (OCRStandardRes.wordsBlock textBlock : arr) {
                String s =  Pattern.compile(REGEX).matcher(textBlock.getWords()).replaceAll("");
                String res = hwNLPUtils.requestPYNLPApi(configs.getCheckRectangText(), s);
                ObjectMapper objectMapper = new ObjectMapper();
                PyResult responseData = objectMapper.readValue(res, PyResult.class);
                if (responseData.getStatus().equals("success")) {
                    textSim = responseData.getResult();
                    result.add(textSim * 100d);
                }else {
                    StringMetric levenshtein = StringMetrics.levenshtein();
                    result.add(levenshtein.compare(configs.getCheckRectangText(), s) * 100d);
                }
            }
        }
        return String.valueOf(result.stream().max(Double::compare).orElse(0.0));
    }

    private String getRateByNoSampleByNLP(List<OCRStandardRes.wordsBlock> arr) throws IOException {
        // 获取模板配置
        List<OcrTempateConfigs> json = this.getJson();
        if (json == null || json.isEmpty()) {
            return "0.0";
        }

        // 过滤出 featureType 为 "3" 的配置
        List<OcrTempateConfigs> list = json.stream()
                .filter(obj -> "3".equals(obj.getFeatureType()))
                .collect(Collectors.toList());

        // 如果没有符合条件的配置，直接返回
        if (list.isEmpty()) {
            return "0.0";
        }

        // 将 OCR 结果和模板配置文本提取为数组
        String[] hwOCRTexts = arr == null ? new String[0] : arr.stream()
                .map(OCRStandardRes.wordsBlock::getWords)
                .filter(Objects::nonNull)
                .toArray(String[]::new);

        String[] configTexts = list.stream()
                .map(OcrTempateConfigs::getOcrText)
                .filter(Objects::nonNull)
                .toArray(String[]::new);

        String result = "0.0";

        // 调用 NLP 接口
        try {
            AiResponse apiResponse = BaiduNLPUtils.textSimilar(hwOCRTexts, configTexts);
            result = apiResponse.getData().get(0);
            String[] results = extractCheckAndExplain(result);
            result = results[0];
        }catch (Exception e){
            log.error(e.getMessage());
        }
        return result;
    }

    /**
     * 根据票据代码获取相似度
     *
     * @param arr OCR识别结果
     * @param config 特征值
     * @return String 结果
     */
    private String getRateByBillCode(List<OCRStandardRes.wordsBlock> arr, OcrTempateConfigs config) throws IOException {
        List<BigDecimal> result = new ArrayList<>();
        List<OcrTempateConfigs> json = this.getJson();
        List<OcrTempateConfigs> list =
                json.stream().filter(obj -> config.getOcrTemplateId().equals(obj.getOcrTemplateId())).collect(Collectors.toList());
        for (OcrTempateConfigs configs : list) {
            List<Double> equals = new ArrayList<>();
            List<Double> likes = new ArrayList<>();
//            List<String> wordsList = arr.stream()
//                    .map(OCRStandardRes.wordsBlock::getWords)
//                    .collect(Collectors.toList());
            BigDecimal divide = BigDecimal.valueOf(configs.getWeight()).divide(BigDecimal.valueOf(100), RoundingMode.HALF_UP);
            if ("equal".equals(configs.getTextFilterExpression())) {
                for (OCRStandardRes.wordsBlock textBlock : arr) {
                    String s = Pattern.compile(REGEX).matcher(textBlock.getWords()).replaceAll("");
                    if (configs.getCheckRectangText().equals(s)) {
                        equals.add(100d);
                    } else {
                        equals.add(0d);
                    }
                Double target = equals.stream().max(Double::compare).orElse(0.0);
                result.add(BigDecimal.valueOf(target).multiply(divide).setScale(2, RoundingMode.HALF_UP));
            }
            if ("like".equals(configs.getTextFilterExpression())) {
                for (OCRStandardRes.wordsBlock textBlock : arr) {
                    // 传递过去两个数组，否则为0。
                    String s = Pattern.compile(REGEX).matcher(textBlock.getWords()).replaceAll("");
                    if(s == null){
                        break;
                    }
                    String[] hwOCRTexts = Optional.ofNullable(arr)
                            .orElse(Collections.emptyList())
                            .stream()
                            .map(block -> Optional.ofNullable(block.getWords()).orElse(""))
                            .toArray(String[]::new);
                    String[] configTexts = {s};

                    String resa = "0.0";

                    // 调用 NLP 接口
                    try {
                        AiResponse apiResponse = BaiduNLPUtils.textSimilar(hwOCRTexts, configTexts);
                        String resulta = apiResponse.getData().get(0);
                        String[] results = extractCheckAndExplain(resulta);
                        resa = results[0];
                        likes.add(Double.valueOf(resa));
                    }catch (Exception e){
                        likes.add(0.0 * 100d);
                    }
                    }
                }
                Double target = likes.stream().max(Double::compare).orElse(0.0);
                result.add(BigDecimal.valueOf(target).multiply(divide).setScale(2, RoundingMode.HALF_UP));
            }
        }
        return String.valueOf(result.stream().reduce(BigDecimal.ZERO, BigDecimal::add));
    }

    /**
     * 判断废票的类别（有样本、无样本有票据代码、无样本无票据代码）
     *
     * @param arr OCR识别结果
     * @return String
     */
    private String getCharacteristic(List<OCRStandardRes.wordsBlock> arr) {
        for (OCRStandardRes.wordsBlock textBlock : arr) {
            String str = Pattern.compile(REGEX).matcher(textBlock.getWords()).replaceAll("");
            if (str.contains("票据代码") || str.contains("证49号") || str.contains("湖北省行政事业单位")) {
                return str;
            }
        }
        return "";
    }

    /**
     * 获取json格式的特征数据
     *
     * @return List<OcrTempateConfigs>
     */
    private List<OcrTempateConfigs> getJson() {
        return getJsonData.getTestData("FeatureConfigs.json", OcrTempateConfigs.class);
    }

    public static String[] extractCheckAndExplain(String content) {
//        JSONObject jsonResponse = JSON.parseObject(responseStr);
//        JSONArray choices = jsonResponse.getJSONArray("choices");
//
//        if (choices == null || choices.isEmpty()) {
//            throw new IllegalArgumentException("No choices available in the response.");
//        }
//
//        JSONObject messageObject = choices.getJSONObject(0).getJSONObject("message");
//        if (messageObject == null) {
//            throw new IllegalArgumentException("Message object is missing.");
//        }
//
//        String content = messageObject.getString("content");
        if (content == null || !content.contains("```json")) {
            throw new IllegalArgumentException("Content is missing or does not contain JSON part.");
        }

        // Extract the JSON part
        String jsonPart = content.split("```json")[1].split("```")[0].trim();
        JSONObject extractedJson = JSON.parseObject(jsonPart);

        // 获取 check 和 explain 值为字符串
        String check = extractedJson != null ? extractedJson.getString("similar") : null;
        String explain = extractedJson != null ? extractedJson.getString("explain") : null;

        // 检查 check 和 explain 是否为 null
        if (check == null || explain == null) {
            throw new IllegalArgumentException("similar or explain value is missing.");
        }

        return new String[]{check, explain};
    }
}